var http = require("http");
var url = require("url");
var sys = require("sys");
var ws = require("./lib/node-ws-client");
var log4js = require('./lib/log4js-node');
var jsbeautify = require('./lib/js-beautify');

var numberOfClientRequests = 5;
var durationOfProcessing = 2000;
var numberOfServerConnections = 2;


log4js.addAppender(log4js.consoleAppender());
logger = log4js.getLogger('revhttp-testing');
logger.setLevel('DEBUG');

var serversHost = '192.168.8.129', serversPort = 9898, serversPath = '/',
    clientsHost = '192.168.8.129', clientsPort = 9899, clientsPath = '/testing/abc';

var serverUri = "http://tirion.zemris.fer.hr:9898/";

var serverPathRegex = "/testing.*";
var realPrefix = "http://tirion.zemris.fer.hr:9899";

var bodyLength = 10;
var applicationBody = "";
for(var i=0; i<bodyLength; i++) {
  applicationBody += "x";
}

var testServerResponse = {body : 'yo', headers : {"content-length" : 2, "access-control-allow-origin" : '*'}, statusCode : 200, reasonPhrase : 'OK', httpVersion :"HTTP/1.1" };

var registrationKey = "";

// server part
function registerService() {
  logger.debug("SERVER - Starting REGISTER request.");
  var websocket = ws.createClient(serverUri);
  
  websocket.addListener('data', function(data) {
    logger.debug("REGISTER response: " + data);
    var message = JSON.parse(data);
    registrationKey = message.revhttp.registrationKey;
    websocket.close();
    for (var i=0; i<numberOfServerConnections; i++) {
      createServerConnection();
    }
  });
  
  websocket.addListener('connect', function() {
    var registerRequest = JSON.stringify({ revhttp : {Method : "REGISTER", pathRegex : serverPathRegex }});
    websocket.write(registerRequest);
    setTimeout(unregisterService, 30000);
  });
}

function unregisterService() {
  logger.debug("SERVER - Starting UNREGISTER request.");
  var websocket = ws.createClient(serverUri);
  
  websocket.addListener('data', function(data) {
    logger.debug("UNREGISTER response: " + data);
    websocket.close();
  });
  
  websocket.addListener('connect', function() {
    var registerRequest = JSON.stringify({ revhttp : {Method : "UNREGISTER", pathRegex : serverPathRegex, registrationKey : registrationKey }});
    websocket.write(registerRequest);
  });
}

function unrequestService(websocket) {
  logger.debug("SERVER - Starting UNREQUEST request.");

  var registerRequest = JSON.stringify({ revhttp : {Method : "UNREQUEST", pathRegex : serverPathRegex, registrationKey : registrationKey }});
  websocket.write(registerRequest);
}

function createServerConnection(requestID, response) {
  logger.debug("SERVER - Starting REQUEST request.");
  var websocket = ws.createClient(serverUri);
  
  websocket.addListener('data', function(data) {
    logger.debug("Response: " + data);
    var message = JSON.parse(data);
    if (message.revhttp.Method === "REQUEST-RESPONSE") {
      return;
    } else if (message.revhttp.Method === "REQUEST") {
      var registerRequest = JSON.stringify({ revhttp : {Method : "REQUEST-RESPONSE", pathRegex : serverPathRegex, registrationKey : registrationKey, requestId : message.revhttp.requestId }, http : testServerResponse});
      websocket.write(registerRequest);
    } else if (message.revhttp.Method === "UNREQUEST-RESPONSE") {
      websocket.close();
    }
  });
  
  websocket.addListener('connect', function() {
    var registerRequest = JSON.stringify({ revhttp : {Method : "REQUEST", pathRegex : serverPathRegex, registrationKey : registrationKey }});
    websocket.write(registerRequest);
    setTimeout(function(wsx) {
      return function() { unrequestService(wsx); };
    }(websocket), 20000);
  });
}

registerService();

// client part
setTimeout( function() {
  logger.debug("Starting client requests.");
  var tests = [];
  tests.finish = function() {
    this.remaining -=1;
    if (this.remaining === 0) {
      logger.debug(jsbeautify.js_beautify(JSON.stringify(this)));
      return;
    }
  }
  tests.remaining = numberOfClientRequests;

  for (var i=0; i<numberOfClientRequests; i++) {
    var test = {};
    tests.push(test);
    test.reqNum = i.toString();
    test.startDate = new Date();
    logger.debug("Starting request " + test.reqNum + '.');
    var clientConnection = http.createClient(clientsPort, clientsHost);
    clientConnection.setTimeout(60000);
    
    var clientRequest = clientConnection.request("POST", clientsPath, {"host": clientsHost, "Content-Length" : bodyLength});
    
    clientRequest.write(applicationBody);
    clientRequest.addListener('response', function(currentTest) {
      return function (clientResponse) {
        clientResponse.setBodyEncoding("utf8");
        clientResponse.addListener("data", function (chunk) { 
          clientResponse.body = typeof clientResponse.body === 'undefined' || clientResponse.body === null ? chunk : clientResponse.body + chunk;});
        clientResponse.addListener("end", function () {
          currentTest.endDate = new Date();
          currentTest.request = JSON.stringify({method : "POST", url : clientsPath, httpVersion : "HTTP/1.1", body : applicationBody, headers : {"host": clientsHost, "Content-Length" : bodyLength}});
          currentTest.response = JSON.stringify({reasonPhrase : clientResponse.reasonPhrase, statusCode : clientResponse.body, body : clientResponse.body, headers : clientResponse.headers});
          logger.debug("Response for request " + currentTest.reqNum.toString() + " received.");
          tests.finish();
        });
      };
    }(test));
    
  clientRequest.close();
  logger.debug("Request " + test.reqNum + " sent.");
  }
}, 5000 );